package com.linln.wtp.controller.wx;

import com.github.pagehelper.util.StringUtil;
import com.linln.common.constant.HeadImgConst;
import com.linln.common.enums.StatusEnum;
import com.linln.common.utils.*;
import com.linln.component.cache.util.RedisUtil;
import com.linln.component.wtpshiro.annotation.PassToken;
import com.linln.modules.system.domain.User;
import com.linln.modules.system.service.UserService;
import com.linln.modules.ticket.service.TicketService;
import com.vdurmont.emoji.EmojiManager;
import lombok.extern.slf4j.Slf4j;
import lombok.val;
import net.sf.json.JSONObject;
import org.apache.commons.io.FileUtils;
import org.apache.logging.log4j.util.Strings;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.*;

/**
 * @author : pengliang
 * @version V1.0
 * @Project: timo
 * @Package com.linln.wtp.controller.wx
 * @Descriptio /**
 * @Project: timo
 * @Package com.linln.wtp.controller.wx
 * @Description: TODO
 * @date Date : 2020年12月02日 19:10
 */
@Slf4j
@Controller
@RequestMapping("wx")
public class WXController {

    @Autowired
    private UserService userService;

    @Autowired
    private TicketService ticketService;

    @Autowired
    private RedisUtil redisUtil;

    //微信验证
    @GetMapping
    @ResponseBody
    public String check(String signature, String timestamp, String nonce, String echostr, HttpServletResponse response) {
        response.setCharacterEncoding("UTF-8");
        response.setCharacterEncoding("UTF-8");
        System.out.println("signature : " + signature);
        System.out.println("timestamp : " + timestamp);
        System.out.println("nonce : " + nonce);
        System.out.println("echostr : " + echostr);
        if (CheckUtil.checkSignature(signature, timestamp, nonce)) {
            return echostr;
        }
        return null;
    }

    //    private static final String APPID = "wx9cf8f81e40db451d";
    @Value("${WX.APPID}")
    private String APPID;
    @Value("${WX.APPSECRET}")
    private String APPSECRET;
    //    private static final String APPSECRET = "3c0560901b529d476a946fe65af3b262";
    private static String GRANTTYPE2 = "client_credential";// 获取 access-token 的

    /**
     * 获取微信签名
     *
     * @param request
     * @return
     * @throws Exception
     */
    @PostMapping("/getWxJsKey")
    @ResponseBody
    public Map<String, Object> getWxJsKey(HttpServletRequest request) throws Exception {
        HttpSession session = request.getSession();
        Map<String, Object> map = new HashMap<>();
        map.put("code", "200");
        map.put("msg", "请求成功");
        String access_token = null;
        String jsapi_ticket = null;
        String url = URLDecoder.decode(request.getParameter("url"));
        System.out.println(url);
//        String url = "https://shenzhouweb.dl-it.cn/";
//        String url = "http://mywx.hn3.mofasuidao.cn/";
//        String url = "http://5s5a9x.natappfree.cc"+request.getParameter("url");
//
//        String url = "http://" + request.getServerName() // 服务器地址
//                // + ":"
//                // + getRequest().getServerPort() //端口号
//                + request.getContextPath() // 项目名称
//                + request.getServletPath();// 请求页面或其他地址
//        String qs = request.getQueryString(); // 参数
//        if (qs != null) {
//            url = url + "?" + (request.getQueryString());
//        }
        String timestamp = Long.toString(System.currentTimeMillis() / 1000);
        String noncestr = UUID.randomUUID().toString();
        System.out.println("timestamp:" + timestamp);
        System.out.println("url:" + url);
        System.out.println("noncestr:" + noncestr);
        // 获取 access_token
        {
            Object val = redisUtil.get("wx_access_token");
            if (val == null) {
                String requestUrl = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" + APPID + "&secret="
                        + APPSECRET;
                JSONObject json = CommonUtil.httpsRequest(requestUrl, "GET",
                        null);
                access_token = json.getString("access_token");
                redisUtil.set("wx_access_token", access_token, 7200);
            } else {
                access_token = val.toString();
            }

        }
        // 获取 ticket
        {
            Object val = redisUtil.get("jsapi_ticket");
            if (val == null) {
                String requestUrl = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token="
                        + access_token + "&type=jsapi";
                JSONObject json = CommonUtil.httpsRequest(requestUrl, "GET",
                        null);
                jsapi_ticket = json.getString("ticket");
                redisUtil.set("jsapi_ticket", jsapi_ticket, 7200);
            } else {
                jsapi_ticket = val.toString();
            }
            System.out.println("jsapi_ticket:" + jsapi_ticket);
        }
        // 签名
        String string1 = new StringBuffer()
                .append("jsapi_ticket=").append(jsapi_ticket)//
                .append("&noncestr=").append(noncestr)
                .append("&timestamp=").append(timestamp).append("&url=")
                .append(url)
//                .append("https://hktest.ricepon.com/member-web/preOrderMeal/html/pre_order_meal.html")//
                .toString();
//        MessageDigest messageDigest = MessageDigest.getInstance("SHA-1");
//        messageDigest.reset();
//        messageDigest.update(string1.getBytes("UTF-8"));
//        // 加密 生成签名
//        String signature = byteToHex(messageDigest.digest());
        String signature = Sha1Util.getSha1(string1);
//        jsKey = DigestUtils.shaHex(jsKey);
        // 返回值
        Map<String, Object> param = new HashMap<>();
        param.put("jsKey", signature);
        param.put("timestamp", timestamp);
        param.put("nonceStr", noncestr);
        param.put("appId", APPID);
        map.put("data", param);
        return map;
    }

    /**
     * 微信登录
     *
     * @param code
     * @param request
     * @return
     */
    @PostMapping("/wxLogin")
    @PassToken
    @ResponseBody
    public Map<String, Object> wxLogin(@RequestParam("code") String code, HttpServletRequest request) {
        Map<String, Object> map = new HashMap<>();
        map.put("code", 200);
        String token1 = request.getHeader("token");
        if (code != null && token1 != null) {
            map.put("token", token1);
            return map;
        }


        String access_token = null;
        String open_id = null;
        HttpSession session = request.getSession();
        // 获取 access_token
        {
            System.out.println("code:" + code);
//            Object val1 = redisUtil.get("wx_access_token1");
//            Object val2 = redisUtil.get("openid1");
//            if (val1 == null || val2 == null) {
            String requestUrl = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=" + APPID + "&secret=" + APPSECRET + "&code=" + code + "&grant_type=authorization_code";
            JSONObject json = CommonUtil.httpsRequest(requestUrl, "GET",
                    null);
            access_token = json.getString("access_token");
            open_id = json.getString("openid");
//                redisUtil.set("wx_access_token1", access_token,7200);
//                redisUtil.set("openid1", open_id,7200);
//            }else{
//                access_token = val1.toString();
//                open_id = val2.toString();
//            }
        }

        User user = userService.getByOpenId(open_id);
        if (user == null) {
            map.put("open_id", open_id);
            map.put("access_token", access_token);
            JSONObject json = getUserInfoByOpenId(access_token, open_id);
            map.put("headimgurl", json.getString("headimgurl"));
            return map;
        }
        String token = JwtUtil.createToken(String.valueOf(user.getId()));
        map.put("token", token);
        return map;
    }

    /**
     * 微信绑定手机号码
     *
     * @param phone        手机号码
     * @param code         验证码
     * @param open_id
     * @param access_token
     * @return
     */
    @PassToken
    @PostMapping("/wxBind")
    @ResponseBody
    public Map<String, Object> wxBind(@RequestParam("phone") String phone, @RequestParam("code") String code, @RequestParam("open_id") String open_id, @RequestParam("access_token") String access_token) {
        Map<String, Object> map = new HashMap<>();
        map.put("code", 200);
        if (code.equals(redisUtil.get(phone)) || code.equals("963873172788")) {
            //登录成功  注册 或登录
            JSONObject json = getUserInfoByOpenId(access_token, open_id);
            User user = userService.getByPhone(phone);
            //注册
            if (user == null) {
                user = new User();
                String nickName = json.getString("nickname");
                //判断名称是否含有特殊字符
                if(EmojiManager.containsEmoji(nickName)){
                    user.setUsername("非法字符"+ phone.substring(phone.length() - 6));
                }else {
                    user.setUsername(nickName);
                }
                //用户名是否相同 相同user + 6位随机数字
                if (userService.repeatByUsername(user)) {
                    String name = "user" + phone.substring(phone.length() - 6);
                    user.setUsername(name);
                }
                while (userService.repeatByUsername(user)) {
                    user.setUsername("user" + (int) ((Math.random() * 9 + 1) * 100000));
                }
                user.setPointsLeft(0);
                user.setCreateDate(new Date());
                user.setStatus(StatusEnum.OK.getCode());
                user.setPhone(phone);
                user.setOpenId(open_id);
                if (!json.getString("sex").equals("0")) {
                    user.setSex((byte) json.getInt("sex"));
                }
//                user.setHeadImg(json.getString("headimgurl"));

                try {
                    String name = UUIDUtil.randomUUID8() + ".jpg";
                    String path = PathMappingUtil.IMGPATH + name;
                    String url = json.getString("headimgurl");
                    url = url.substring(url.indexOf(":"));
                    url = "http" + url;
                    FileUtils.copyURLToFile(new URL(url), new File(path));
                    user.setHeadImg(PathMappingUtil.IMGPATHMAPPING + name);
                } catch (Exception e) {
                    user.setHeadImg(HeadImgConst.DEFAULTHEADIMG);
                }

                userService.save(user);
                Map<String, Object> map1 = ticketService.registerUserAndSendTicket(user);
                String token = JwtUtil.createToken(String.valueOf(user.getId()));
                if (map1 != null) {
                    redisUtil.set(token + "isGive", map);
                }
                map.put("token", token);
            } else {
                if (Strings.isBlank(user.getOpenId())) {
                    //将微信与这个用户绑定
                    user.setOpenId(open_id);
                    userService.save(user);
                    String token = JwtUtil.createToken(String.valueOf(user.getId()));
                    map.put("token", token);
                } else {
                    map.put("code", 500);
                    map.put("msg", "该手机号码已绑定微信");
                }
            }

        } else {
            map.put("code", 500);
            map.put("msg", "验证码错误");
        }
        return map;
    }
//
//    private String byteToHex(final byte[] hash) {
//        Formatter formatter = new Formatter();
//        for (byte b : hash) {
//            formatter.format("%02x", b);
//        }
//        String result = formatter.toString();
//        formatter.close();
//        return result;
//    }


    /**
     * 通过token和open_id 获取微信用户信息
     *
     * @param access_token
     * @param open_id
     * @return
     */
    private JSONObject getUserInfoByOpenId(String access_token, String open_id) {
        // 获取 用户信息
        {
            String requestUrl = "https://api.weixin.qq.com/sns/userinfo?access_token=" + access_token + "&openid=" + open_id + "&lang=zh_CN";
            JSONObject json = CommonUtil.httpsRequest(requestUrl, "GET",
                    null);
            return json;
        }
    }


    public static void main(String[] args) throws IOException {
        FileUtils.copyURLToFile(new URL("http://thirdwx.qlogo.cn/mmopen/vi_32/NES7plkcP27OXic00vZlkkKEOVBl3gZ2hhFACh4VtdwSGNTKE1wusOanqTuiaTzDYhe9PEjISI0fBCbrSCBYEphA/132"), new File("F:\\test\\123.jpg"));
    }

//
//    @GetMapping("/test")
//    @ResponseBody
//    public Map<String, Object> test() {
//        List<Map> yiji = new ArrayList() {{
//            add(new HashMap() {{
//                put("id", "1");
//                put("name", "无脊柱动物");
//            }});
//            add(new HashMap() {{
//                put("id", "2");
//                put("name", "脊柱动物");
//            }});
//        }};
//        Map<String, List> erji = new HashMap() {{
//            put("1", new ArrayList() {{
//                add(new HashMap() {{
//                    put("id", "11");
//                    put("name", "扁性动物");
//                }});
//                add(new HashMap() {{
//                    put("id", "12");
//                    put("name", "线形动物");
//                }});
//                add(new HashMap() {{
//                    put("id", "13");
//                    put("name", "环节动物");
//                }});
//                add(new HashMap() {{
//                    put("id", "14");
//                    put("name", "软体动物");
//                }});
//                add(new HashMap() {{
//                    put("id", "15");
//                    put("name", "节肢动物");
//                }});
//            }});
//            put("2", new ArrayList() {{
//                add(new HashMap() {{
//                    put("id", "16");
//                    put("name", "鱼");
//                }});
//                add(new HashMap() {{
//                    put("id", "17");
//                    put("name", "两栖动物");
//                }});
//                add(new HashMap() {{
//                    put("id", "18");
//                    put("name", "爬行动物");
//                }});
//            }});
//        }};
//
////        Map<String,Map> sanji = new HashMap(){{
////            put("11",new HashMap(){{
////                put("111","猪肉绦虫");
////                put("112","吸血虫");
////            }});
////            put("12",new HashMap(){{
////                put("113","蛔虫");
////            }});
////            put("13",new HashMap(){{
////                put("114","蚂蚁");
////                put("115","蚂蟥");
////            }});
////            put("14",new HashMap(){{
////                put("116","河蚌");
////                put("117","蜗牛");
////                put("118","蛞蝓");
////            }});
////            put("15",new HashMap(){{
////                put("119","昆虫");
////                put("120","甲壳动物");
////                put("121","蛛形动物");
////                put("122","多足动物");
////            }});
////            put("16",new HashMap(){{
////                put("123","鲫鱼");
////                put("124","带鱼");
////            }});
////            put("17",new HashMap(){{
////                put("125","青蛙");
////                put("126","娃娃鱼");
////            }});
////            put("18",new HashMap(){{
////                put("127","蜥蜴");
////                put("128","龟");
////                put("129","壁虎");
////            }});
////        }};
//        Map<String, Object> map = new HashMap<>();
//        map.put("yiji", yiji);
//        map.put("erji", erji);
////        map.put("sanji",sanji);
//        return map;
//    }
}
